/******************************************************************************
;	OS.c 
;	Matthew Villarrubia, Yves Santos 4/08/2011
******************************************************************************/
#include "os.h"
#include "LM3SXXXX.H"
#include "../driverlib/gpio.h"
#include<stdio.h>

static int Distance;//units are in inches
static long long startTime;
static long long endTime;
static int callNum; 

//****************************PingHandler**************************************
//	This is the interrupt handler for the ping sensor
//! \param None
//! \return None
//*****************************************************************************
void
PingHandler(void){

	GPIOPinIntClear(GPIO_PORTC_BASE, GPIO_PIN_5);

	if(callNum%2 == 0){
		GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x80);
		startTime = OS_Time();	
	}
	else{
		GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x00);
		endTime = OS_Time();
	}
	callNum++;
}

//*************************begin_measuring*************************************
//	Sets up the interrupts for rising and falling edges on the GPIO pin for
//	the Ping))) sensor
//! \param None
//! \return None
//*****************************************************************************
void
begin_measuring(void) {
	GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_5);
	GPIOIntTypeSet(GPIO_PORTC_BASE,GPIO_PIN_5,GPIO_BOTH_EDGES);
	GPIOPinIntClear(GPIO_PORTC_BASE, GPIO_PIN_5);
	GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_5);
	IntPrioritySet(INT_GPIOC, 0);
    IntEnable(INT_GPIOC);
    IntMasterEnable();
}

//***************************end_measuring*************************************
//	Disables the interrupts for rising and falling edges on the GPIO pin for
//	the Ping))) sensor
//! \param None
//! \return None
//*****************************************************************************
void
end_measuring(void){
	GPIOPinIntDisable(GPIO_PORTC_BASE, GPIO_PIN_5);
	IntDisable(INT_GPIOC);
}

//****************************Ping_Measure*************************************
//	Call this function to get the distance from the ping sensor.
//! \param Pointer to the calling thread
//! \return Distance in inches
//*****************************************************************************
int 
Ping_Measure(OS_TCB* this){
	int i;

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	end_measuring();

	callNum = 0;
    
	IntMasterDisable();
	
	GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_5);
	
	GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0x20); //generate pulse
		
	for(i=0; i < 50; i++);
    
    GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0x00);       //finish pulse

	begin_measuring();   //configure to input and wait for rising edge
						//interrupts enabled in this function
	OS_Sleep(this,10);
	end_measuring();

	Distance = (int)(endTime -startTime);
	Distance = (int)((double)Distance / (double)3687);
	Distance = (int)(((double)Distance - (double)(0.3679))/(double)(2.0222));
	
	if(Distance > 40 || Distance < 0){
		Distance = -1;
		
	}	
	//Distance = (unsigned int)(((double)(Distance)*(double)(2.0222))+(double)(0.3679));
	
	return Distance;	
}
